home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
usenet
/
sources
/
volume2
/
fun
/
evo_life.1
next >
Wrap
Internet Message Format
|
1988-12-07
|
22KB
Path: xanth!ames!mailrus!ulowell!page
From: page@swan.ulowell.edu (Bob Page)
Newsgroups: comp.sources.amiga
Subject: v02i094: evo-life - evolving life simulation
Message-ID: <10523@swan.ulowell.edu>
Date: 6 Dec 88 23:52:41 GMT
Organization: University of Lowell, Computer Science Dept.
Lines: 495
Approved: page@swan.ulowell.edu
Submitted-by: ain@k.cc.purdue.edu (Pat-bob White)
Posting-number: Volume 2, Issue 94
Archive-name: fun/evo-life.1
Here is an evolving life program I wrote several years ago in
AmigaBasic. I have other (extended) versions is anybody is
interested.
# This is a shell archive.
# Remove everything above and including the cut line.
# Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: Shell Archiver
# Run the following text with /bin/sh to create:
# readme
# evolving_life_140
# tracefile
# This archive created: Tue Nov 22 11:08:37 1988
# By: Pat-bob White (PUCC Land, USA)
cat << \SHAR_EOF > readme
These two programs go together and were written in Amiga Basic.. first a
bit about what they are and what they do:
Evolving Life 140 is a program I wrote about 2 years ago when I wanted to
explore the concept of genetic learning. I abstracted real life into an
environment (sort of an electronic petri dish) and amoebe-like cells (sort of
e-amoeba).
The environment consists of a 24x38 matrix of locations that cells can
occupy. Each location has a food level which is incremented by one each step,
and is decrememnted when the cells eat. The levels within the locations are
represented by a spectrum from red to blue (red = lots of food). One step is
executed from each cell, then the environment is updated.. repeats till all
cells die or the machine crashes :-)
The cells are represented by black dots in the locations. They run
"genetic programs" that have 6 different kind of steps: move, reproduce, eat,
goto, if hungry, and nop -- each step uses up internalized food.
Move: a cell tries to move to a (randomly selected) adjacent empty location,
Reproduce: reproduction is sexual; A cell on the make first finds a mate (a
cell in an adjacent location), then an empty adjacent location for the
child cell, and finally, creates the child cell's "genetic program" by
copying half from it's own program, and half from the mate's program.
Then, 1 random step in the new program is changed to a random value (on
the theory that mutations are good for the soul :-)
eat: internalize food from the environment (if there is any),
goto: goto a new step in the program (goes back to my own theory that loops
are essential to any programming language),
if hungry: if internalized food level is below some amount, then go to some
program step (same theory).. since I used bytes to represent each step,
this put a limt of 32 steps on the size of a program (I found out that
a cell only uses about 8 steps, but needed about 16 locations to save
them -- the other 8 steps being spent as wasted space... when I tried to
shorten the program to only 8 steps, I couldn't get colonies to start).
nop: every language needs one.. and what else was I to do with the other
3 3-bit patterns I wasn't using?
There is a special cell that I used for keeping a tracefile -- cell 1. (I
represented the cells with an array of strings, so this was the cell in the
first position of the array). This cells is marked with a red dot in it's
center, and each time a cell that is born reuses that array location, I write a
snapshot of the current matrix, and where the cells are into the tracefile.
The tracefile program is the other one here, and all it does is display
a tracefile on the screen. It's comments document it fairly well, so I won't
bother to say anthing else about it.
implementation:
Both programs are implemented in Amiga Basic, and I use the graphics
heavily.. so a bit of description about Amiga graphics is in order for those
who don't (aren't fortunate enough? :-) have an Amiga... (those who have an
Amiga may find my terminology confusing since much of it is from the meager
graphics background I have)
The Amiga has screens and windows. A screen is where the colors (bitplanes)
are defined, and the actual storage is attached to. A window is a graphics
viewport onto a screen that has it's own internal coordinate system.. when
something is drawn into a window, the OS performs any necessary clipping and
coordinate translation, and then actually renders it into the screen's memory
(therefore, windows appear to have their own memory but really don't).
Therefore, I open a new 32-color screen to get access to a whole set of 32
colors, open a window on it to render into, and then start rendering. One
confusing call (basic's fault, not mine) is the line drawing command, which I
use to draw filled rectangles by specifying the upper left and lower right
corners of the rectangle, and adding the "bf" option to draw a box and fill it.
PALLETTE sets a color in the pallette.
POINT returns the color of the referenced pixel.
LOCATE moves the cursor to the desired character position.
CVI converts a two byte string to the integer it represents in binary
(it's much the same as "asc() * 256 + asc()").
MKI$ is the opposite of CVI -- converts an integer into a string containing
the 2-byte binary representation.
These are the comments from the evolving life program and it's corresponding
tracefile program:
Evolving Life 140
-----------------
max number of cells is 140
cells are kept as basic strings
there are 8 types of program steps a cell program knows: move,
reproduce, eat, goto, if hungry, and 3 nop's. move moves a cell in
any 1 of te 8 possible directions, eat takes food from the environment,
goto unconditionally branches to another step i the program, if hungry
branches if the cell is hungry, and nop's do nothing. All actions
cause food consumption of the internalized food (via eat).
death is caused by falling off the end of the program, running out
of food, or executing more than the max number of steps allowed (the
lifespan).
A trace snapshot is written to a file each time a cell is born into
cell 1's storage (the cell storage is reused since I have only a small
number of them -- so, everytime a cell is born that reuses storage
position 1, a snapshot is taken). The snapshots files are generally
large (>200K) and are viewed through the "Tracefile" program.
Food levels are represented by a spectrum of colors -- red is max
food, dark blue is min (somehow, purple slipped in as a high-but-not-
max color for food.. don't really know why, but I suspect it is because
I didn't want it to feel lonely :-)
The program runs till all the cells die.. alt least it is supposed to
do that.
The stats at the bottome are: nc = number of currently alive cells,
tc = total number of cells that have ever lived or are currently living,
ns = total number of cell-program steps have been done.
Have fun reading the code -- it is commented but mostly consists of
mid$ accesses to get characters out of the cell storage -- the cell's
program steps are stored as characters in a basic string.
Tracefile
---------
Tracefile -- written to display the trace files saved by
Evolving Live 140. Written sometime arround 6/86
Patrick White
currently (11/88) reachable at ain@k.cc.purdue.edu
displays the tracefile -- one frame at a time. the stats at the bottom
of the picture are: which screen is being displayed, (nc) the number of
cells on the screen, (tc) the total number of cells that have ever
lived, (ns) the total number of cell-program-steps that have been
executed.
The colors on the screen indicate: red is most food, dark blue is least
food. THe outer square is the fool level scaled on a screen-wise basis
with red being greatest amount of food. The inner square is the food
level scaled from 0 to max possible - again red is max. I did it this
way because I couldn't decided how to do it -- so, naturally, I did it
both ways :-)
When finished with the data file, the program waits for a mouse-click
in the display window before closing the window/screen. If you stop
the program in any other way, the screen and window will be left open
and take memory -- best to let it finish on it's own.
Oh, BTW, trace snapshots are taken whenever a cell is born into cell 1
(since I have to reuse the cell locations, this makes soms sense).
I also have a version in C for the Amiga somewhere -- I didn't submit it
because I'm not sure if it even compiles anymore -- if you want it, let me know
and I'll send it to you.
Well, that's about it... (I think it's documented enough now :-)
If you have any questions, please ask...
-- Pat White
ARPA/UUCP: k.cc.purdue.edu!ain BITNET: PATWHITE@PURCCVM PHONE: (317) 743-8421
U.S. Mail: 320 Brown St. apt. 406, West Lafayette, IN 47906
SHAR_EOF
cat << \SHAR_EOF > evolving_life_140
REM Evolving Life 140 (140 cells max)
REM Patrick White written -- I have no idea but somewhere around 6/86
REM currently (11/88) reachable at ain@k.cc.purdue.edu
REM max number of cells is 140
REM cells are kept as basic strings
REM there are 8 types of program steps a cell program knows: move,
REM reproduce, eat, goto, if hungry, and 3 nop's. move moves a cell in
REM any 1 of te 8 possible directions, eat takes food from the environment,
REM goto unconditionally branches to another step i the program, if hungry
REM branches if the cell is hungry, and nop's do nothing. All actions
REM cause food consumption of the internalized food (via eat).
REM death is caused by falling off the end of the program, running out
REM of food, or executing more than the max number of steps allowed (the
REM lifespan).
REM A trace snapshot is written to a file each time a cell is born into
REM cell 1's storage (the cell storage is reused since I have only a small
REM number of them -- so, everytime a cell is born that reuses storage
REM position 1, a snapshot is taken). The snapshots files are generally
REM large (>200K) and are viewed through the "Tracefile" program.
REM Food levels are represented by a spectrum of colors -- red is max
REM food, dark blue is min (somehow, purple slipped in as a high-but-not-
REM max color for food.. don't really know why, but I suspect it is because
REM I didn't want it to feel lonely :-)
REM The program runs till all teh cells die.. alt least it is supposed to
REM do that.
REM The stats at teh bottome are: nc = number of currently alive cells,
REM tc = total number of cells that have ever lived or are currently living,
REM ns = total number of cell-program steps have been done.
REM Have fun reading the code -- it is commented but mostly consists of
REM mis$ accesses to get characters out of the cell storage -- the cell's
REM program steps are stored as characters in a basic string.
REM life
CLEAR,20000,5000
RANDOMIZE TIMER
INPUT "filename of trace file ";filename$ : OPEN "O",#1,filename$
ncels = 139 : nstps = 50 : clrs = 16 : alimit = 94 : ns& = 0
nc% = 0 : tc& = 0
DIM food%(37,23), cell$(ncels)
REM initialize screen
SCREEN 1,300,200,4,1
WINDOW 2,"Evolving Life Display",(0,0)-(290,180),0,1
PALETTE 0, 0,0,0 : PALETTE 1, 0,0,1 : PALETTE 2, 0,.29,1
PALETTE 3, 0,.57,1 : PALETTE 4, 0,.86,1 : PALETTE 5, 0,1,.86
PALETTE 6, 0,1,.57 : PALETTE 7, 0,1,.29 : PALETTE 8, 0,1,0
PALETTE 9, .29,1,0 : PALETTE 10,.57,1,0 : PALETTE 11,.86,1,0
PALETTE 12,1,.86,0 : PALETTE 13,1,.57,0 : PALETTE 14,1,.29,0
PALETTE 15,1,0,0 : CLS : mf = 8510 : stp = mf / (clrs - 2)
FOR i = 0 TO 37
FOR j = 0 TO 23
food%(i,j) = i*j*10
LINE (i*7,j*7)-(i*7+6,j*7+6),(INT(food%(i,j) / stp) + 1),bf
NEXT j
NEXT i
FOR i = 9 TO 15 : LINE (266,i*7+2)-(272,i*7+4),15,bf : NEXT i
REM initialize cells
FOR c = 0 TO 69
x = INT (RND * 38) : y = INT (RND * 24)
IF POINT(x*7+3,y*7+3) > 0 THEN
a% = INT (RND * mf) : b% = INT (RND * mf / 2)
cell$(c) = CHR$(x) + CHR$(y) + MKI$(a%) + MKI$(b%) + MKI$(INT(RND*alimit)) + MKI$(0)
LINE (x*7+2,y*7+2)-(x*7+4,y*7+4),0,bf
FOR i = 1 TO nstps : x = INT (RND * 256) : cell$(c) = cell$(c) + CHR$(x) : NEXT i
nc% = nc% + 1
END IF
NEXT c
tc& = nc%
LOCATE 22,1 : PRINT "fre= ";FRE(0);FRE(-1);FRE(-2);
GOSUB pic
REM quit stuff
ON ERROR GOTO e
ON MOUSE GOSUB quit
MOUSE ON
runagain: REM run cell programs
REM increment food in environment
PALETTE 0,.2,.2,.2 : ns& = ns& + 1
FOR i = 0 TO 37
FOR j = 0 TO 23
a% = food%(i,j) : food%(i,j) = a% + 1 : IF food%(i,j) > mf THEN food%(i,j) = mf
IF INT(a% / stp) <> INT(food%(i,j) / stp) THEN
x = POINT(i*7+3,j*7+3) : LINE (i*7,j*7)-(i*7+6,j*7+6),INT(food%(i,j) / stp) + 1,bf
IF x = 0 THEN LINE (i*7+2,j*7+2)-(i*7+4,j*7+4),0,bf
END IF
NEXT j
NEXT i
PALETTE 0,0,0,0
FOR c = 0 TO ncels
IF cell$(c) <> "" THEN
x = ASC( MID$( cell$(c),1,1)) : y = ASC( MID$( cell$(c),2,1))
IF (CVI( MID$(cell$(c), 7,2)) > alimit) OR (CVI( MID$( cell$(c), 3, 2)) < 0) THEN
LINE (x*7,y*7)-(x*7+6,y*7+6),INT(food%(x,y)/ stp)+1, bf
cell$(c) = "" : nc% = nc% - 1
ELSE
MID$(cell$(c), 7,2) = MKI$( CVI( MID$(cell$(c),7,2)) + 1)
IF (y > 8) AND (y < 16) THEN MID$( cell$(c), 11 + INT(RND*(LEN(cell$(c))-10)), 1) = CHR$( INT(RND*256) )
a% = CVI( MID$( cell$(c), 9, 2) ) : y = ASC( MID$( cell$(c), 11 + a%, 1) )
a% = a% + 1
IF a% > (LEN( cell$(c)) - 11) THEN : MID$( cell$(c), 7, 2) = MKI$( alimit + 1) : a% = 0
MID$( cell$(c), 9, 2) = MKI$( a% )
ON (y AND 7)+1 GOSUB mov, repro, eat, gto, ifhung, nop, nop, nop
END IF
END IF
NEXT c
LOCATE 22,1 : PRINT "nc="; nc%;" tc=";tc&;" ns=";ns&;
GOTO runagain
e: WINDOW CLOSE 2 : SCREEN CLOSE 1 : CLOSE #1 : prinr ERR
END
pic: REM store a picture of the screen
WRITE #1,mf;stp;ns&;tc&;nc%;cell$(0)
FOR i = 0 TO 37
WRITE #1,food%(i,0);food%(i,1);food%(i,2);food%(i,3);food%(i,4);food%(i,5);food%(i,6);food%(i,7);food%(i,8);food%(i,9);food%(i,10);food%(i,11)
WRITE #1,food%(i,12);food%(i,13);food%(i,14);food%(i,15);food%(i,16);food%(i,17);food%(i,18);food%(i,19);food%(i,20);food%(i,21);food%(i,22);food%(i,23)
NEXT i
FOR i = 0 TO ncels : IF cell$(i) <> "" THEN WRITE #1,MID$(cell$(i),1,2)
NEXT i
RETURN
quit: REM end
WINDOW CLOSE 2 : SCREEN CLOSE 1 : CLOSE #1
PALETTE 0, 0,.5,1 : PALETTE 1, 1,1,1 : PALETTE 2, 0,0,0
PALETTE 3, 1,.73,0
END
nop: REM no op
MID$(cell$(c), 3, 2) = MKI$( CVI( MID$( cell$(c), 3, 2)) - 10) : RETURN
mov: REM move in specified direction
MID$( cell$(c), 3, 2) = MKI$( CVI( MID$( cell$(c), 3,2) ) - 20)
REM erase old cell position
a% = (y AND 224) / 32
x = ASC( MID$( cell$(c), 1, 1) ) : y = ASC( MID$( cell$(c), 2, 1) ) : x1 = x : y1 = y
LINE (x*7,y*7)-(x*7+6,y*7+6),INT( food%(x,y) / stp) + 1,bf
REM pick direction and move cell if possible
IF a% = 0 THEN x = x - 1: y = y - 1
IF a% = 1 THEN y = y - 1
IF a% = 2 THEN y = y - 1: x = x + 1
IF a% = 3 THEN x = x + 1
IF a% = 4 THEN x = x + 1: y = y + 1
IF a% = 5 THEN y = y + 1
IF a% = 6 THEN y = y + 1: x = x - 1
IF a% = 7 THEN x = x - 1
x = (x + 38) MOD 38
y = (y + 24) MOD 24
IF POINT( x*7 + 3, y*7 + 3) <> 0 THEN
MID$(cell$(c), 1, 1) = CHR$( x ) : MID$(cell$(c), 2, 1) = CHR$( y )
LINE (x*7+2, y*7+2)-(x*7+4,y*7+4),0,bf
ELSE
LINE (x1*7+2, y1*7+2)-(x1*7+4, y1*7+4),0,bf
END IF
RETURN
repro: REM reproduce if a cell nearby
MID$( cell$(c), 3, 2) = MKI$( CVI( MID$( cell$(c), 3, 2)) - 60)
IF nc% = ncels THEN RETURN
REM determine which cell to mate with
a% = 0 : b% = 0 : x1 = ASC( MID$( cell$(c),1,1)) : y1 = ASC( MID$( cell$(c),2,1))
l1: IF (cell$(a%) <> "") AND (a% <> c) THEN
x = ASC( MID$( cell$(a%), 1, 1) ) : y = ASC( MID$( cell$(a%), 2, 1) )
IF ((x<x1-1) OR (x>x1+1) OR (y<y1-1) OR (y>y1+1)) AND (a% < ncels) THEN a%=a%+1 : b% = 1
ELSE
IF a% < ncels THEN a% = a% + 1 : b% = 1
END IF
IF b% = 1 THEN b% = 0 : GOTO l1
IF (c = a%) OR (cell$(a%) = "") OR (x<x1-1) OR (x>x1+1) OR (y<y1-1) OR (y>y1+1) THEN RETURN
REM determine free cell
b% = 0
l2: IF (cell$(b%) <> "") AND (b% < ncels) THEN b% = b% + 1 : GOTO l2
IF cell$(b%) <> "" THEN RETURN
REM find empty spot for child cell
c% = x1 : d% = y1
FOR i = 1 TO 15
x = INT(RND * 3) - 1 + x1 : y = INT(RND * 3) - 1 + y1
IF ((POINT(x*7+3,y*7+3) > 0) AND (x > 0) AND (x < 38) AND (y > 0) AND (y < 24)) THEN c% = x : d% = y
NEXT i
IF ((c% = x1) AND (d% = y1)) THEN RETURN
REM create child
nc% = nc% + 1 : tc& = tc& + 1
x = LEN( cell$(c) ) : y = LEN( cell$(a%) )
cell$(b%) = MID$(cell$(c), 1, INT(x / 2) ) + MID$(cell$(a%), INT(y / 2), y - INT(y / 2) )
MID$(cell$(b%), 1, 1) = CHR$(c%) : MID$(cell$(b%), 2, 1) = CHR$(d%)
LINE (c%*7+2,d%*7+2)-(c%*7+4,d%*7+4),0,bf
a% = INT( CVI( MID$( cell$(c), 3, 2) ) / 2)
MID$( cell$(c), 3, 2) = MKI$( a% ) : MID$( cell$(b%), 3, 2)= MKI$( a% )
MID$(cell$(b%), 7, 2) = MKI$( 0 ) : MID$(cell$(b%), 9, 2) = MKI$( 0 )
REM mutate one step in child
REM x = LEN( cell$(b%) )
REM a = RND : b = RND : MID$( cell$(b%), 11 + INT( a * (x - 10)), 1) = CHR$( INT( b * 256 ))
IF b% = 0 THEN GOSUB pic
RETURN
eat: REM eat food
MID$( cell$(c), 3, 2) = MKI$( CVI( MID$( cell$(c), 3, 2)) - 20)
x = ASC( MID$( cell$(c), 1, 1)) : y = ASC( MID$( cell$(c), 2, 1))
IF food%(x,y) > 100 THEN
food%(x,y) = food%(x,y) - 100
MID$( cell$(c), 3,2) = MKI$( CVI( MID$(cell$(c),3,2)) + 100)
ELSE
MID$( cell$(c), 3,2) = MKI$( CVI( MID$(cell$(c),3,2)) + food%(x,y))
food%(x,y) = 0
END IF
LINE (x*7,y*7)-(x*7+6,y*7+6),INT(food%(x,y)/ stp) + 1,bf
LINE (x*7+2,y*7+2)-(x*7+4,y*7+4),0,bf
RETURN
gto: REM jump in program
MID$( cell$(c), 3, 2) = MKI$( CVI( MID$( cell$(c), 3, 2)) - 20)
a% = CVI( MID$( cell$(c), 9, 2)) : a% = ASC( MID$( cell$(c), a% + 11, 1)) MOD (LEN(cell$(c)) - 10)
MID$( cell$(c), 9,2) = MKI$( a% )
RETURN
ifhung: REM if hungry then jump in program
MID$( cell$( c), 3,2) = MKI$( CVI( MID$( cell$(c), 3,2)) -40)
a% = CVI( MID$( cell$(c), 9, 2)) : x = ASC( MID$( cell$(c), a% + 11, 1)) MOD (LEN(cell$(c)) - 10)
IF CVI( MID$( cell$(c), 3,2)) < CVI( MID$( cell$(c), 5,2)) THEN a% = x ELSE a% = a% + 1
IF a% > (LEN(cell$(c)) - 11) THEN a% = 0
MID$( cell$(c), 9, 2) = MKI$( a% )
RETURN
SHAR_EOF
cat << \SHAR_EOF > tracefile
REM Tracefile -- written to display the trace files saved by
REM Evolving Live 140. Written sometime arround 6/86
REM Patrick White
REM currently (11/88) reachable at ain@k.cc.purdue.edu
REM displays the tractefile -- one frame at a time. the stats at the bottom
REM of the picture are: which screen is being displayed, (nc) the number of
REM cells on the screen, (tc) the total number of cells that have ever
REM lived, (ns) the total number of cell-program-steps that have been
REM executed.
REM The colors on the screen indicate: red is most food, dark blue is least
REM food. THe outer square is the fool level scaled on a screen-wise basis
REM with red being greatest amount of food. The inner square is the food
REM level scaled from 0 to max possible - again red is max. I did it this
REM way because I couldn't decided how to do it -- so, naturally, I did it
REM both ways :-)
REM When finished with the data file, the program waits for a mouse-click
REM in the display window before closing the window/screen. If you stop
REM the program in any other way, the screen and window will be left open
REM and take memory -- best to let it finish on it's own.
REM Oh, BTW, trace snapshots are taken whenever a cell is born into cell 1
REM (since I have to reuse the cell locations, this makes soms sense).
REM trace viewer
INPUT "trace filename";filename$
OPEN "I",#1,filename$
DIM f%(37,23)
sc = 0
SCREEN 1,300,200,4,1
WINDOW 2,filename$,(0,0)-(290,180),0,1
PALETTE 0, 0,0,0 : PALETTE 1, 0,0,1 : PALETTE 2, 0,.29,1
PALETTE 3, 0,.57,1 : PALETTE 4, 0,.86,1 : PALETTE 5, 0,1,.86
PALETTE 6, 0,1,.57 : PALETTE 7, 0,1,.29 : PALETTE 8, 0,1,0
PALETTE 9, .29,1,0 : PALETTE 10, .57,1,0 : PALETTE 11, .86,1,0
PALETTE 12, 1,.86,0 : PALETTE 13, 1,.57,1 : PALETTE 14, 1,.29,0
PALETTE 15, 1,0,0
nxt:
sc = sc + 1
INPUT #1,mf,stp,ns&,tc&,nc%
c$ = INPUT$ (64, #1) : c$ = MID$( c$, 3, 60)
REM PRINT nc%;"***";c$;"***"
FOR i = 0 TO 37
INPUT #1,f%(i,0),f%(i,1),f%(i,2),f%(i,3),f%(i,4),f%(i,5),f%(i,6),f%(i,7),f%(i,8),f%(i,9),f%(i,10),f%(i,11)
INPUT #1,f%(i,12),f%(i,13),f%(i,14),f%(i,15),f%(i,16),f%(i,17),f%(i,18),f%(i,19),f%(i,20),f%(i,21),f%(i,22),f%(i,23)
NEXT i
max = f%(0,0)
FOR i = 0 TO 37 : FOR j = 0 TO 23
IF f%(i,j) > max THEN max = f%(i,j)
NEXT j : NEXT i
mstp = max / 14
FOR i = 0 TO 37
FOR j = 0 TO 23
LINE (i*7,j*7)-(i*7+6,j*7+6),INT(f%(i,j) / mstp) + 1,b
LINE (i*7+1,j*7+1)-(i*7+5,j*7+5),INT(f%(i,j) / stp) + 1,bf
NEXT j
NEXT i
FOR i = 1 TO nc%
a$ = INPUT$ (5,#1) : x = ASC( MID$( a$, 2,1)) : y = ASC( MID$( a$, 3,1))
REM PRINT i;"***";a$;"***",x, y
LINE (x*7+2,y*7+2)-(x*7+4,y*7+4),0,bf
IF i = 1 THEN LINE (x*7+3,y*7+3)-(x*7+3,y*7+3),15,bf
NEXT i
LOCATE 22,1 : PRINT sc;"nc= ";nc%;"tc= ";tc&;"ns= ";ns&;
IF EOF(1) THEN GOTO cnt ELSE GOTO nxt
cnt:
BEEP
ON MOUSE GOSUB quit
MOUSE ON
slp: SLEEP
GOTO slp
quit:
CLOSE #1 : WINDOW CLOSE 2 : SCREEN CLOSE 1
PALETTE 0, .4,.6,1 : PALETTE 1, 1,1,1 : PALETTE 2, 0,0,0
PALETTE 3, 1,.73,0
END
SHAR_EOF
# End of shell archive
exit 0
--
Bob Page, U of Lowell CS Dept. page@swan.ulowell.edu ulowell!page
Have five nice days.